package cn.aiweiyi.qingjing.coupon.distribution.entity;

import cn.aiweiyi.qingjing.coupon.comm.constant.CouponStatus;
import cn.aiweiyi.qingjing.coupon.comm.vo.CouponTemplateSDK;
import cn.aiweiyi.qingjing.coupon.distribution.converter.CouponSerializer;
import cn.aiweiyi.qingjing.coupon.distribution.converter.CouponStatusConverter;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import javax.persistence.*;
import java.util.Date;

/**
 * @author 青衿
 * @Date 2020/11/19 9:04
 * 优惠券(用户领取的优惠券记录)实体表
 **/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@EntityListeners(AuditingEntityListener.class)
@Table(name = "coupon")
@JsonSerialize(using = CouponSerializer.class)
public class Coupon {
    /**
     * 自增主键
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", nullable = false)
    private Integer id;

    /**
     * 关联优惠券模板的主键(逻辑外键)
     */
    @Column(name = "template_id", nullable = false)
    private Integer templateId;

    /**
     * 领取用户
     */
    @Column(name = "user_id", nullable = false)
    private Long userId;

    /**
     * 优惠券码
     */
    @Column(name = "coupon_code", nullable = false)
    private String couponCode;

    /**
     * 领取时间
     */
    @CreatedDate
    @Column(name = "assign_time", nullable = false)
    private Date assignTime;

    /**
     * 优惠券状态
     */
    @Column(name = "status", nullable = false)
    @Convert(converter = CouponStatusConverter.class)
    private CouponStatus status;

    /**
     * 用户优惠券对象的模板信息
     */
    @Transient
    private CouponTemplateSDK templateSDK;

    //一个无效的 Coupon对象,用于避免缓存雪崩时存入空(无效) 对象的时候
    //声明为静态,且用静态,该独享维持单例的形式,可以反复使用
    //比每次用都new一个新的对象要高效,避免GC频繁垃圾回收导致JVM性能下降
    @Transient
    public static final Coupon invalidCoupon;

    static {
        invalidCoupon = new Coupon();
        invalidCoupon.setId(-1); //-1是一个错误的优惠券id
    }

    /**
     * 构造优惠券
     */
    public Coupon(Integer templateId, Long userId, String couponCode,
                  CouponStatus status) {
        this.templateId = templateId;
        this.userId = userId;
        this.couponCode = couponCode;
        this.status = status;
    }
}
